/**
 * HTTPS Request实现
 */
package com.kotiln.lgc.lib_network.javahttp;

import java.io.BufferedOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.net.MalformedURLException;
import java.net.ProtocolException;
import java.net.SocketTimeoutException;
import java.net.URL;
import java.net.UnknownHostException;
import java.security.GeneralSecurityException;
import java.security.cert.X509Certificate;

import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;
import javax.net.ssl.X509TrustManager;

import com.easytouch.core.http.BaseHttpRequest;
import com.easytouch.core.utils.Log;

/**
 * @author gulin
 *
 */
public abstract class SslHttpRequest extends BaseHttpRequest
{
	private Log mLogger = new Log("SslHttpRequest.txt");
	private myX509TrustManager xtm = new myX509TrustManager();

    private myHostnameVerifier hnv = new myHostnameVerifier();
    
    private String mPostData;
    
    private String mCharset = "UTF-8";
    
    private String mContentType = "application/x-www-form-urlencoded"; //"text/html";

	public SslHttpRequest(String url)
	{
		super(url);
		doInit();
	}

	public SslHttpRequest(String url,String tradeType)
	{
		super(url, tradeType);
		doInit();
	}
	
	public SslHttpRequest(String url,String tradeType, String post)
	{
		super(url, tradeType);
		setPostData(post);
		doInit();
	}
	
	public SslHttpRequest(String url,String tradeType, String post, String charset)
	{
		super(url, tradeType);
		mCharset = charset;
		setPostData(post);
		doInit();
	}
	
	public SslHttpRequest(String url,String tradeType, String post, String charset, String contentType)
	{
		super(url, tradeType);
		mCharset = charset;
		setPostData(post);
		this.mContentType = contentType;
		doInit();
	}
	
	public void setPostData(String post)
	{
		this.mPostData = post;
	}
	
	private void doInit()
	{
		SSLContext sslContext = null;
        try {
            sslContext = SSLContext.getInstance("TLS"); //或SSL
            X509TrustManager[] xtmArray = new X509TrustManager[] {xtm};
            sslContext.init(null, xtmArray, new java.security.SecureRandom());
        } catch (GeneralSecurityException e) {
            e.printStackTrace();
        }
        if (sslContext != null) {
            HttpsURLConnection.setDefaultSSLSocketFactory(sslContext.getSocketFactory());
        }
        HttpsURLConnection.setDefaultHostnameVerifier(hnv);
	}
	
	@Override
	protected Result doInBackground(Void...params)
	{
		URL realurl = null;
		InputStream in = null;
		HttpsURLConnection conn = null;
		StringBuffer sBuffer = null;
		
		try {
			realurl = new URL(mUrl);
			conn = (HttpsURLConnection) realurl.openConnection();
			conn.setDoInput(true); 
			conn.setReadTimeout(20000);
			conn.setConnectTimeout(20000);
			conn.setRequestMethod(mTradeType);
			if(mTradeType.equalsIgnoreCase("POST"))
			{
//				conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
//			    conn.setRequestProperty("Charset", mCharset);
				conn.setRequestProperty("Content-Type", mContentType + ";charset=" + mCharset);
				
			    if(mPostData != null)
			    {
			    	BufferedOutputStream out = new BufferedOutputStream(conn.getOutputStream());
			    	byte[] bytes = mPostData.getBytes(mCharset);
			    	out.write(bytes, 0, bytes.length);
			    	out.flush();
			    	out.close();
			    }
			}
			if(conn.getResponseCode() == HttpsURLConnection.HTTP_OK)
			{
				sBuffer = new StringBuffer();
			    byte[] buf = new byte[1024];  
			    in = conn.getInputStream();
			    for (int n; (n = in.read(buf)) != -1;)
			    {  
			        sBuffer.append(new String(buf, 0, n, mCharset));  
			    }  
			}else{
				return new Result(-1, "read error");
			}
			
		} catch (MalformedURLException e) {
			return new Result(-90, "MalformedURLException");
		} catch (ProtocolException e) {
			return new Result(-91, "ProtocolException");
		} catch (UnsupportedEncodingException e) {
			return new Result(-92, "UnsupportedEncodingException");
		} catch(SocketTimeoutException e){
			return new Result(-93, "SocketTimeoutException");
		}catch (UnknownHostException  e) {
			return new Result(-95, "UnknownHostException");
		}catch (IOException e) {
			return new Result(-96, "IOException");
		}
		finally
		{
			try
			{
				if(in != null) in.close();
			} catch (IOException e) {
				e.printStackTrace();
			}  
			if(conn != null) conn.disconnect();
		}
		return new Result(0, sBuffer.toString());
	}
	
	@Override
	protected void onPostExecute(Result result)
	{
//		super.onPostExecute(result);
		afterTrade(result);
	}

	protected abstract void afterTrade(Result result);
	
	
	class myX509TrustManager implements X509TrustManager
	{
	    
	    public void checkClientTrusted(X509Certificate[] chain, String authType)
	    {
	    }

	    public void checkServerTrusted(X509Certificate[] chain, String authType)
	    {
//	        System.out.println("cert: " + chain[0].toString() + ", authType: " + authType);
	    }

	    public X509Certificate[] getAcceptedIssuers()
	    {
	        return null;
	    }
	}
	
	class myHostnameVerifier implements HostnameVerifier
	{

	    public boolean verify(String hostname, SSLSession session)
	    {
//	        System.out.println("Warning: URL Host: " + hostname + " vs. " + session.getPeerHost());
	        return true;
	    }
	}
}
